package cn.ltgodm.template.web.controller.user;

import cn.ltgodm.template.common.annotation.Log;
import cn.ltgodm.template.common.constant.UserConstants;
import cn.ltgodm.template.common.domain.AjaxResult;
import cn.ltgodm.template.common.domain.TreeSelect;
import cn.ltgodm.template.common.enums.BusinessType;
import cn.ltgodm.template.common.utils.StringUtils;
import cn.ltgodm.template.user.domain.param.MenuParam;
import cn.ltgodm.template.user.domain.param.MenuQueryParam;
import cn.ltgodm.template.common.domain.vo.MenuVO;
import cn.ltgodm.template.user.service.MenuService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author ltgodm
 * @date 2024-03-28 19:17:21
 * 菜单管理
 */
@RestController
@RequestMapping("/user/menu")
@Tag(name = "菜单管理")
@ApiSupport(author = "ltgodm")
public class MenuController {

    @Resource
    private MenuService menuService;

    @GetMapping("/list")
    @Operation(summary = "分页获取菜单列表")
    @PreAuthorize("hasAuthority('system:menu:query')")
    public IPage<MenuVO> list(@ParameterObject MenuQueryParam menuQueryParam) {
        return menuService.selectMenuList(menuQueryParam);
    }

    @GetMapping("/{menuId}")
    @Operation(summary = "获取菜单详细信息")
    @PreAuthorize("hasAuthority('system:menu:query')")
    public AjaxResult getInfo(@PathVariable Long menuId) {
        return AjaxResult.success(menuService.selectMenuById(menuId));
    }

    @GetMapping("/tree")
    @Operation(summary = "获取菜单树形结构列表")
    @PreAuthorize("hasAuthority('system:menu:query')")
    public AjaxResult tree(@ParameterObject MenuQueryParam menuQueryParam) {
        return AjaxResult.success(menuService.selectMenuTree(menuQueryParam));
    }

    @GetMapping("/roleMenuTree/{roleId}")
    @Operation(summary = "加载对应角色菜单列表树")
    @PreAuthorize("hasAuthority('system:menu:query')")
    public AjaxResult roleMenuTree(@PathVariable("roleId") Long roleId) {
        AjaxResult ajax = AjaxResult.success();
        //所有菜单列表
        List<TreeSelect> menus = menuService.selectMenuTree(new MenuQueryParam());
        //角色已有菜单列表
        List<Long> checkedKeys = menuService.selectMenuListByRoleId(roleId);
        ajax.put("checkedKeys", checkedKeys);
        ajax.put("menus", menus);
        return ajax;
    }

    @PostMapping
    @Operation(summary = "新增菜单")
    @PreAuthorize("hasAuthority('system:menu:add')")
    @Log(title = "菜单管理", businessType = BusinessType.INSERT)
    public AjaxResult add(@RequestBody MenuParam menuParam) {
        if (!menuService.checkMenuNameUnique(menuParam)) {
            return AjaxResult.error("新增菜单'" + menuParam.getMenuName() + "'失败，菜单名称已存在");
        } else if (UserConstants.YES_FRAME.equals(menuParam.getIsFrame().toString()) && !StringUtils.ishttp(menuParam.getPath())) {
            return AjaxResult.error("新增菜单'" + menuParam.getMenuName() + "'失败，地址必须以http(s)://开头");
        }
        int row = menuService.insertMenu(menuParam);
        if (row > 0) {
            return AjaxResult.success();
        } else {
            return AjaxResult.error();
        }
    }

    @PutMapping
    @Operation(summary = "修改菜单")
    @PreAuthorize("hasAuthority('system:menu:edit')")
    @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
    public AjaxResult edit(@RequestBody MenuParam menuParam) {
        if (!menuService.checkMenuNameUnique(menuParam)) {
            return AjaxResult.error("修改菜单'" + menuParam.getMenuName() + "'失败，菜单名称已存在");
        } else if (UserConstants.YES_FRAME.equals(menuParam.getIsFrame().toString()) && !StringUtils.ishttp(menuParam.getPath())) {
            return AjaxResult.error("修改菜单'" + menuParam.getMenuName() + "'失败，地址必须以http(s)://开头");
        } else if (menuParam.getMenuId().equals(menuParam.getParentId())) {
            return AjaxResult.error("修改菜单'" + menuParam.getMenuName() + "'失败，上级菜单不能选择自己");
        }
        int row = menuService.updateMenu(menuParam);
        if (row > 0) {
            return AjaxResult.success();
        } else {
            return AjaxResult.error();
        }
    }


    @DeleteMapping("/{menuId}")
    @Operation(summary = "删除菜单")
    @PreAuthorize("hasAuthority('system:menu:remove')")
    @Log(title = "菜单管理", businessType = BusinessType.DELETE)
    public AjaxResult remove(@PathVariable Long menuId) {
        if (menuService.hasChildByMenuId(menuId)) {
            return AjaxResult.error("存在子菜单,不允许删除");
        }
        if (menuService.checkMenuExistRole(menuId)) {
            return AjaxResult.error("菜单已分配,不允许删除");
        }
        int row = menuService.deleteMenuById(menuId);
        if (row > 0) {
            return AjaxResult.success();
        } else {
            return AjaxResult.error();
        }
    }
}
